package com.A21.GuoSai.demo.atom_adjust.config;

import com.A21.GuoSai.demo.atom_adjust.mapper.AtomServiceMapper;
import com.A21.GuoSai.demo.atom_adjust.utils.AtomServiceUtils;
import com.A21.GuoSai.demo.service_entity.annotation.Author;
import com.A21.GuoSai.demo.service_entity.annotation.OutPutParam;
import com.A21.GuoSai.demo.service_entity.annotation.VariableType;
import com.A21.GuoSai.demo.service_entity.entity.atom.AtomServicePojo;
import com.A21.GuoSai.demo.service_entity.entity.atom.DynamicVarPojo;
import com.A21.GuoSai.demo.service_entity.entity.atom.StaticVarPojo;
import com.A21.GuoSai.demo.service_entity.entity.atom.VarPojo;
import io.camunda.zeebe.spring.client.ZeebeClientLifecycle;
import io.camunda.zeebe.spring.client.bean.MethodInfo;
import io.camunda.zeebe.spring.client.bean.ParameterInfo;
import io.camunda.zeebe.spring.client.bean.value.ZeebeWorkerValue;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.Closeable;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Aspect
@Component
public class ZeebeVaribleConfig implements CommandLineRunner {

    @Autowired
    ZeebeClientLifecycle clientLifecycle;

    @Autowired
    AtomServiceMapper atomServiceMapper;

    private void getZeebeVarible() throws NoSuchFieldException, IllegalAccessException {
        //提取出ZeebeClientLifecycle中的所有JobWorkerImpl
        List<Closeable> list= AtomServiceUtils.getJobWorkerImpl(clientLifecycle);
        //首先清除静态变量和动态变量表中的同名变量
        atomServiceMapper.deleteSameAtom();
        //从数据库中提取出所有原子服务的静态变量名
        List<List<StaticVarPojo>> atom_stavar=this.getStaticVar();
        List<List<DynamicVarPojo>> atom_dynvar=this.getDynamicVar();

        list.stream().forEach(closeable -> {
            try {
                //提取出JobWorkerImpl中的ZeebeWorkerValue
                ZeebeWorkerValue zeebeWorkerValue=AtomServiceUtils.getWorkerValueFromJobWorker(closeable);

                //获取原子服务的名称和Id
                String workerName= zeebeWorkerValue.getName();
                Integer atomId=atomServiceMapper.getAtomIdByName(workerName);

                //提取出@ZeebeWorker注解到的methodInfo
                MethodInfo methodInfo = zeebeWorkerValue.getMethodInfo();
                //@Author是直接添加在方法上的，所以要从methodInfo中获取
                Optional<Author> annotation = methodInfo.getAnnotation(Author.class);
                Optional<OutPutParam> outputParam = methodInfo.getAnnotation(OutPutParam.class);
//                System.out.println("annotation.size():"+annotation.stream().toArray().length);
                annotation.stream().forEach(author -> {
//                    System.out.println(author.author()+"--"+author.attributeConnnect());
                    atomServiceMapper.updateAtom_Author_Attr(author.author(),author.attributeConnnect(),atomId);
                });
                outputParam.stream().forEach(param->{
                    StaticVarPojo staticVarPojo=new StaticVarPojo();
                    staticVarPojo.setAtomId(atomId);
                    staticVarPojo.setS_name(param.paramName());
                    staticVarPojo.setTypeClass(param.paramClass());
                    staticVarPojo.setVarDesc(param.desc());
                    staticVarPojo.setIsInput(false);
                    staticVarPojo.setMethodInfo(methodInfo.getBean().getClass().getCanonicalName()+"."+methodInfo.getMethodName());
                    //如果没有这个参数，则进行添加
                    if(notHave_sta(atom_stavar,atomId, param.paramName())){
                        atomServiceMapper.insertAtomStaticVar(staticVarPojo);
                    }
                });
                //从methodInfo中提取出所有的参数
                List<ParameterInfo> parameters = methodInfo.getParameters();
                //@VariableType是添加在参数上的，所以从参数身上获取到相关注解信息即可
                for(ParameterInfo parameterInfo : parameters){
                    Parameter parameter=parameterInfo.getParameterInfo();
                    //获取参数类型信息
                    VariableType variableType = parameter.getAnnotation(VariableType.class);
                    if(variableType != null){
                        VarPojo var=new VarPojo();
                        var.setAtomId(atomId);
                        var.setTypeClass(parameter.getType());
                        var.setVarDesc(variableType.desc());
                        var.setMethodInfo(methodInfo.getBean().getClass().getCanonicalName()+"."+methodInfo.getMethodName());

                        if(variableType.isStatic()&& notHave_sta(atom_stavar,var.getAtomId(),parameterInfo.getParameterName())){
                            StaticVarPojo staticVarPojo = new StaticVarPojo(var);
                            staticVarPojo.setS_name(parameterInfo.getParameterName());
                            atomServiceMapper.insertAtomStaticVar(staticVarPojo);
                        }
                        else if(!variableType.isStatic()&& notHave_dyn(atom_dynvar,var.getAtomId(), parameterInfo.getParameterName())){
                            DynamicVarPojo dynamicVarPojo= new DynamicVarPojo(var);
                            dynamicVarPojo.setD_name(parameterInfo.getParameterName());
                            atomServiceMapper.insertAtomDynamicVar(dynamicVarPojo);
//                            atomServiceMapper.deleteDyn_StaAtom(dynamicVarPojo);
                        }

//                        System.out.println(parameter.getType().getCanonicalName()+"--"+variableType.desc()+"，是否为静态变量:"+variableType.isStatic());
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 从数据库中提取出所有原子服务的静态变量名
     * @return
     */
    public List<List<StaticVarPojo>> getStaticVar(){
        List<AtomServicePojo> atomServicePojoList=atomServiceMapper.getAllAtomServices();
        return atomServicePojoList.stream().map(
                atomServicePojo -> {
                    return atomServiceMapper.getAtomStaticVar(atomServicePojo);
                }
        ).collect(Collectors.toList());
//        atomServiceMapper.deleteSameAtom();
    }


    /**
     * 从数据库中提取出所有原子服务的动态变量名
     * @return
     */
    public List<List<DynamicVarPojo>> getDynamicVar(){
        List<AtomServicePojo> atomServicePojoList=atomServiceMapper.getAllAtomServices();
        return atomServicePojoList.stream().map(
                atomServicePojo -> {
                    return atomServiceMapper.getAtomDynamicVar(atomServicePojo);
                }
        ).collect(Collectors.toList());
//        atomServiceMapper.deleteSameAtom();
    }


    /**
     * 判断数据库中是否已经存在该变量
     * @param list
     * @param id
     * @param name
     * @return
     */
    public boolean notHave_sta(List<List<StaticVarPojo>> list, Integer id, String name){
        for (List<StaticVarPojo> atom : list){
            for (StaticVarPojo stavar:atom){
                if(stavar.getAtomId().equals(id) && stavar.getS_name().equals(name))return false;
            }
        };
        return true;
    }

    public boolean notHave_dyn(List<List<DynamicVarPojo>> list,Integer id,String name){
        for (List<DynamicVarPojo> atom : list){
            for (DynamicVarPojo dynVar:atom){
                if(dynVar.getAtomId().equals(id) && dynVar.getD_name().equals(name))return false;
            }
        };
        return true;
    }


    @Override
    public void run(String... args) throws Exception {
        getZeebeVarible();
    }
}
